#include "Stokes/V_Coarsen_Patch_Strategy.h"

void
Stokes::V_Coarsen_Patch_Strategy::postprocessCoarsen_2D
(SAMRAI::hier::Patch& coarse,
 const SAMRAI::hier::Patch& fine,
 const SAMRAI::hier::Box& ,
 const SAMRAI::hier::IntVector& )
{
  /* Fix up the boundary elements by iterating through the boundary
     boxes */

  /* We only care about edges, not corners, so we only iterate over
     edge boundary boxes. */
  const std::vector<SAMRAI::hier::BoundaryBox>
    &boundaries=coarse_fine[fine.getPatchLevelNumber()]->getEdgeBoundaries(coarse.getGlobalId());
     
  boost::shared_ptr<SAMRAI::pdat::SideData<double> > v_fine =
    boost::dynamic_pointer_cast<SAMRAI::pdat::SideData<double> >
    (fine.getPatchData(v_id));
  boost::shared_ptr<SAMRAI::pdat::SideData<double> > v =
    boost::dynamic_pointer_cast<SAMRAI::pdat::SideData<double> >
    (coarse.getPatchData(v_id));

  TBOX_ASSERT(v);
  TBOX_ASSERT(v_fine);
  TBOX_ASSERT(v_fine->getDepth() == v->getDepth());
  TBOX_ASSERT(v->getDepth() == 1);

  SAMRAI::hier::Box gbox(v_fine->getGhostBox());
  SAMRAI::hier::Index ip(1,0), jp(0,1);
  for(size_t mm=0; mm<boundaries.size(); ++mm)
    {
      SAMRAI::hier::Box bbox=boundaries[mm].getBox();
      int location_index=boundaries[mm].getLocationIndex();

      SAMRAI::hier::Index
        lower=SAMRAI::hier::Index::coarsen(bbox.lower(),
                                           SAMRAI::hier::Index(2,2)),
        upper=SAMRAI::hier::Index::coarsen(bbox.upper(),
                                           SAMRAI::hier::Index(2,2));

      for(int j=lower(1); j<=upper(1); ++j)
        for(int i=lower(0); i<=upper(0); ++i)
          {
            /* Fix vx */
            if(location_index==0)
              {
                SAMRAI::pdat::SideIndex coarse(SAMRAI::hier::Index(i,j),0,
                                               SAMRAI::pdat::SideIndex::Upper);
                SAMRAI::pdat::SideIndex center(coarse*2);
                if(center[1]>=gbox.lower(1) && center[1]<gbox.upper(1))
                  {
                    (*v)(coarse)=((*v_fine)(center) + (*v_fine)(center+jp))/2;
                  }
              }
            else if(location_index==1)
              {
                SAMRAI::pdat::SideIndex coarse(SAMRAI::hier::Index(i,j),0,
                                               SAMRAI::pdat::SideIndex::Lower);
                SAMRAI::pdat::SideIndex center(coarse*2);
                if(center[1]>=gbox.lower(1) && center[1]<gbox.upper(1))
                  {
                    (*v)(coarse)=((*v_fine)(center) + (*v_fine)(center+jp))/2;
                  }
              }
            /* Fix vy */
            else if(location_index==2)
              {
                SAMRAI::pdat::SideIndex coarse(SAMRAI::hier::Index(i,j),1,
                                               SAMRAI::pdat::SideIndex::Upper);
                SAMRAI::pdat::SideIndex center(coarse*2);
                if(center[0]>=gbox.lower(0) && center[0]<gbox.upper(0))
                  {
                    (*v)(coarse)=((*v_fine)(center) + (*v_fine)(center+ip))/2;
                  }
              }
            else if(location_index==3)
              {
                SAMRAI::pdat::SideIndex coarse(SAMRAI::hier::Index(i,j),1,
                                               SAMRAI::pdat::SideIndex::Lower);
                SAMRAI::pdat::SideIndex center(coarse*2);
                if(center[0]>=gbox.lower(0) && center[0]<gbox.upper(0))
                  {
                    (*v)(coarse)=((*v_fine)(center) + (*v_fine)(center+ip))/2;
                  }
              }
            else
              {
                abort();
              }
          }
    }
}
